package com.teamsun.service;

import com.teamsun.entity.HttpResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>通过httpClient访问外部系统</p>
 */
@Service
public class HttpClientService implements BeanFactoryAware {

    @Autowired
    private RequestConfig requestConfig;

    private BeanFactory beanFactory;

    /**
     * 处理get请求
     * @param url 请求地址
     * @return
     */
    public HttpResult doGet(String url) throws Exception {
        // 创建get请求
        HttpGet httpGet = new HttpGet();
        httpGet.setConfig(requestConfig);
        CloseableHttpResponse httpResponse = null;

        try {
            // 执行请求
            httpResponse = getHttpClient().execute(httpGet);
            return new HttpResult(httpResponse.getStatusLine().getStatusCode(),EntityUtils.toString(httpResponse.getEntity(), "UTF-8"));
        } finally {
            if(httpResponse != null) {
                httpResponse.close();
            }
        }
    }

    /**
     * 处理带参数的get请求
     * @param url 请求地址
     * @param param 请求参数
     * @return
     */
    public HttpResult doGet(String url, Map<String, String> param) throws Exception{
        if(param == null) {
            this.doGet(url);
        }

        URIBuilder uriBuilder = new URIBuilder(url);
        for(Map.Entry<String, String> entry : param.entrySet()) {
            uriBuilder.addParameter(entry.getKey(), entry.getValue());
        }

        return this.doGet(uriBuilder.build().toString());
    }

    /**
     * 处理不带参数的POST请求
     * @param url
     * @return
     */
    public HttpResult doPost(String url) throws Exception {
        return this.doPost(url, null);
    }

    /**
     * 处理带参数的POST请求
     * @param url
     * @param param
     * @return
     */
    public HttpResult doPost(String url, Map<String, String> param) throws Exception{
        HttpPost httpPost = new HttpPost(url);
        if(param != null && param.size() > 0) {
            List<NameValuePair> pairs = new ArrayList<NameValuePair>();
            for(Map.Entry<String, String> entry : param.entrySet()) {
                pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }

            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(pairs);
            httpPost.setEntity(formEntity);
        }

        httpPost.setConfig(this.requestConfig);
        httpPost.setHeader("User-Agent",
                "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36");

        CloseableHttpResponse response = null;
        try {
            response = getHttpClient().execute(httpPost);
            return new HttpResult(response.getStatusLine().getStatusCode(), EntityUtils.toString(response.getEntity(), "UTF-8"));
        } finally {
            if(response != null) {
                response.close();
            }
        }
    }

    /**
     * 处理提交JSON数据的POST请求
     * @param url
     * @param json
     * @return
     */
    public HttpResult doPostJson(String url, String json) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(this.requestConfig);

        if(StringUtils.isNotBlank(json)) {
            StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(stringEntity);
        }

        CloseableHttpResponse response = null;
        try {
            response = getHttpClient().execute(httpPost);
            return new HttpResult(response.getStatusLine().getStatusCode(), EntityUtils.toString(response.getEntity(), "UTF-8"));
        } finally {
            if(response != null) {
                response.close();
            }
        }
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    private CloseableHttpClient getHttpClient() {
        return this.beanFactory.getBean(CloseableHttpClient.class);
    }
}
